﻿using CREAPA.RepositorioADO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CREAPA.Dominio;
using System.Data;
using CrystalDecisions.CrystalReports.Engine;
using System.IO;
using CREAPA.UL.Web.Models;
using System.Globalization;

namespace CREAPA.UL.Web.Controllers
{
    public class ContrachequeController : Controller
    {
        ContrachequeRepositorioADO ccADO = new ContrachequeRepositorioADO();
        ContrachequeItensRepositorioADO cciADO = new ContrachequeItensRepositorioADO();
        RelatorioRepositorioADO relADO = new RelatorioRepositorioADO();
        FuncionarioRepositorioADO funcADO = new FuncionarioRepositorioADO();
        CREAPA.Dominio.Funcionario funcionario = new CREAPA.Dominio.Funcionario();
        private siscreaEntitiesBD db = new siscreaEntitiesBD();

        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

        [Authorize]
        public ActionResult RelatorioCC()
        {
            string usu = User.Identity.Name;
            int ano;
            FuncionarioRepositorioADO funcADO = new FuncionarioRepositorioADO();
            CREAPA.Dominio.Funcionario funcionario = new CREAPA.Dominio.Funcionario();
            funcionario = funcADO.ListarPorLogin(User.Identity.Name);
            ViewBag.funcionarioNome = funcionario.Pessoa.Nome;
            //Verifica se é o primeiro mês do ano. Se for, mostra os dados do ano anterior
            if (DateTime.Now.Month != 1)
                ano = DateTime.Now.Year;
            else
                ano = DateTime.Now.Year-1;

            ViewBag.Ano = ano;
            
            var ListaCC = relADO.ListarRelatorioCC(ano.ToString(), funcionario.Pessoa.CPF);
            return View(ListaCC);
        }

        [Authorize]
        public ActionResult Consultar()
        {
            return View();
        }

        [Authorize]
        public ActionResult Visualizar(int TipoFolha, int Ano, int Mes)
        {
            funcionario = funcADO.ListarPorLogin(User.Identity.Name);
            var cc = ccADO.ListarContrachequeFunc(funcionario.Pessoa.CPF, Ano, Mes.ToString(), TipoFolha);

            var ListaCCI = cciADO.ListarContrachequeItens(funcionario.Pessoa.CPF, cc.Ano, cc.Mes, TipoFolha);
            ViewBag.ListaCCI = ListaCCI;

            ViewBag.Titulo = DescricaoFolha(TipoFolha, Ano, Mes.ToString());

            if (cc == null)

                return HttpNotFound();
            return View(cc);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Consultar(Contracheque cc)
        {
            funcionario = funcADO.ListarPorLogin(User.Identity.Name);

            if (ModelState.IsValid)
            {
                try
                {
                    var ListaCC = ccADO.ListarContracheque(funcionario.Pessoa.CPF, cc.Ano, cc.Mes);
                    ViewBag.ListaCC = ListaCC;

                    return View();
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "Não foi possível carregar as informações, tente novamente mais tarde, se o problema persistir, contate o administrador do sistema." + Environment.NewLine + "Erro: " + ex.Message);
                }
            }
            return View();
        }

        public ActionResult Imprimir(int TipoFolha, int Ano, int Mes)
        {
            funcionario = funcADO.ListarPorLogin(User.Identity.Name);
            ReportADO report = new ReportADO();

            if (ValidarEntradaCC(TipoFolha, Ano, Mes))
            {
                DataTable dt = report.GetContracheque(funcionario.Pessoa.CPF, Ano, Mes, TipoFolha);

                ReportClass rptH = new ReportClass();

                rptH.FileName = Server.MapPath("~/Reports/ContraCheque.rpt");
                rptH.Load();
                rptH.SetDataSource(dt);

                Stream stream = rptH.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);

                rptH.Close();
                rptH.Dispose();

                return File(stream, "application/pdf");
            }
            else
            {
                TempData["notice"] = "Parâmetros incorretos. Tente novamente.";
                return RedirectToAction("../OS/Erro");
            }
        }

        [Authorize]
        public ActionResult Processar()
        {
            string usu = User.Identity.Name;
            var permissao = new SelectList(db.FuncionarioPermissoes.Where(p => p.Login == usu && (p.Permissao == 4 || p.Permissao == 11)));

            if (permissao.Count() > 0)
            {
                return View();
            }
            else
            {
                TempData["notice"] = "Você não tem permissão para acessar essa página. É necessária a permissão: 0004";
                return RedirectToAction("../Os/Erro");
            }
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Processar(Contracheque cc)
        {
            funcionario = funcADO.ListarPorLogin(User.Identity.Name);
            string filename = "";
            string resultado = "";

            if (ModelState.IsValid)
            {
                try
                {
                    if (Request.Files["FileUpload1"].FileName != "")//Algum arquivo foi anexado
                    {
                        foreach (string upload in Request.Files)
                        {
                            if (Request.Files[upload].ContentLength == 0) continue;
                            string pathToSave = Server.MapPath("~/Views/Documentos/contracheque/");
                            filename = "CC" + cc.TipoFolha.ToString() + cc.Mes + cc.Ano + ".txt";
                            Request.Files[upload].SaveAs(Path.Combine(pathToSave, filename));
                        }
                        //Faz o processsamento do arquivo que foi anexado anteriormente
                        resultado = ProcessaContraCheque(cc.TipoFolha, cc.Ano, cc.Mes);
                    }
                    //ProcessaContraCheque(cc.TipoFolha, cc.Ano, cc.Mes);

                    if (resultado != "")
                    {
                        TempData["notice"] = "Não foi processado o arquivo o mês e ano do arquivo difere do mês e ano selecionado.";
                        return RedirectToAction("../Os/Erro");
                    }
                    else
                    {
                        TempData["cc"] = "Contracheque processado com Sucesso";
                        return RedirectToAction("Processar");
                    }

                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "Não foi possível carregar as informações, tente novamente mais tarde, se o problema persistir, contate o administrador do sistema." + Environment.NewLine + "Erro: " + ex.Message);
                }
            }
            return View();
        }


        public string ProcessaContraCheque(int TipoFolha, int Ano, string Mes)
        {
            //string gravou;
            string mesFolha = "";
            string anoFolha = "";

            System.IO.StreamReader sr;
            //DALFuncionario dalfuncionario = new DALFuncionario();
            //DALContraCheque dalContraCheque = new DALContraCheque();
            ContrachequeRepositorioADO ccADO = new ContrachequeRepositorioADO();

            string linhaAtual, linhaCompleta = "";
            int num_linha = 1;
            bool achouLinhaInic = false;//verifica se o início dos campos dos itens do Contra-cheque foi encontrado
            List<ContrachequeItens> listaItens = new List<ContrachequeItens>();//Inicialização do ArrayList inicial
            int linha_total_vant = 100;//Guarda a linha do campo TOTAL VANTAGENS
            int num_linha_fim_func = 2;//Guarda a última linha com os dados do funcionário
            string CPF = "";
            float total_desc = 0, total_vant = 0, val_liq = 0;
            float salarioBase = 0, baseFGTS = 0, baseIRRF = 0;
            int total_cc = 0;
            string erro = "";
            string teste = "";
            string PathArq = Server.MapPath(@"..\Views\Documentos\contracheque\");//caminho
            PathArq = PathArq + "CC" + TipoFolha.ToString() + Mes + Ano + ".txt";//nome do arquivo

            // Verifica se o Arquivo não Existe
            if (!System.IO.File.Exists(PathArq))
            {
                throw (new System.IO.FileNotFoundException("Não foi Possível Localizar o Arquivo Especificado"));
            }
            else
            {
                // Inicializa o StreamReader
                sr = new System.IO.StreamReader(PathArq);
                // O método IndexOf retorna valor -1 caso a string não seja encontrada.

                while (!sr.EndOfStream)
                {
                    num_linha++;
                    // Recupera a Linha
                    linhaAtual = sr.ReadLine();
                    linhaCompleta = linhaCompleta + linhaAtual + "\n";

                    if (num_linha == num_linha_fim_func + 4)
                    {
                        mesFolha = linhaAtual.Substring(62, 3);
                        anoFolha = linhaAtual.Substring(66, 4);
                    }
                    //Guarda o campo MATRICULA:
                    //o campo MATRICULA está 06 (SEis) linhas depois do início dos dados do funcionário
                    if (num_linha == num_linha_fim_func + 1)
                    {
                        CPF = linhaAtual.Substring(80, 11);
                    }

                    //Última linha dos proventos e descontos
                    //Guarda o campo TOTAL VANTAGENS
                    if (linhaAtual.IndexOf("TOTAL VANTAGENS:") != -1)
                    {
                        achouLinhaInic = false;
                        total_vant = float.Parse(linhaAtual.Substring(60, 10));
                        linha_total_vant = num_linha;//Guarda a linha onde está o campo TOTAL VANTAGENS
                    }

                    //Guarda o campo TOTAL DESCONTOS:
                    //o campo TOTAL DESCONTOS está 01 (UMA) linha depois do campo TOTAL VANTAGENS
                    if (num_linha == linha_total_vant + 1)
                        total_desc = float.Parse(linhaAtual.Substring(60, 10));

                    //Guarda o campo SAL. LIQUIDO:
                    //o campo SAL. LIQUIDO está 02 (DUAS) linha depois do campo TOTAL VANTAGENS
                    if (num_linha == linha_total_vant + 2)
                        val_liq = float.Parse(linhaAtual.Substring(60, 10));

                    //Adiciona os itens dos proventos e descontos 
                    if (achouLinhaInic == true)
                    {
                        ContrachequeItens item = new ContrachequeItens();
                        item.TipoFolha = TipoFolha;
                        item.Mes = Mes;
                        item.Ano = Ano;
                        item.CPF = CPF;
                        item.Codigo = linhaAtual.Substring(24, 3);
                        item.Descricao = linhaAtual.Substring(28, 22);
                        item.Valor = float.Parse(linhaAtual.Substring(61, 9));
                        if (linhaAtual.Substring(70, 1) == "-")
                            item.TipoValor = false;//Negativo (Descontos)
                        else
                            item.TipoValor = true;//Positivo (Proventos)
                        listaItens.Add(item);

                        //Guarda os valores para algumas variáveis
                        if (item.Codigo == "002") salarioBase = item.Valor;
                        if (item.Codigo == "500")//Base FGTS
                            baseFGTS = float.Parse(linhaAtual.Substring(51, 9));
                        if (item.Codigo == "501")//Base imposto de renda
                        {
                            teste = linhaAtual.Substring(51, 9);
                            if (teste != "         ")
                                baseIRRF = float.Parse(linhaAtual.Substring(51, 9)); ;
                        }
                    }

                    //verifica quando começam as linhas dos proventos e descontos
                    // O cabelhaço aparece  10 (DEZ) linhas depois do início dos dados do funcionário
                    //a variável achouLinhaInic = true é encontrado linha de cabeçalho dos proventos e descontos
                    //Texto do cabeçalho: "COD VERBA                       BASE     VALOR"
                    if (num_linha == num_linha_fim_func + 10)
                    {
                        achouLinhaInic = true;
                    }

                    //Verifica quando termina os dados de um funcionário
                    // O fim dos dados do funcionários aparece  03 (TRÊS) linhas depois do campo TOTAL VANTAGENS
                    //Texto do cabeçalho: "------------------------------------------------0"
                    if (num_linha == linha_total_vant + 3)
                    {
                        Contracheque objContraCheque = new Contracheque();
                        objContraCheque.Descricao = DescricaoFolha(TipoFolha, Ano, Mes);
                        objContraCheque.CPF = CPF;
                        objContraCheque.Ano = Ano;
                        objContraCheque.Mes = Mes;
                        objContraCheque.Total_vant = total_vant;
                        objContraCheque.Total_desc = total_desc;
                        objContraCheque.Val_liq = val_liq;
                        objContraCheque.Salariobase = salarioBase;
                        objContraCheque.BaseFGTS = baseFGTS;
                        objContraCheque.FGTSDesc = 8 * baseFGTS / 100;
                        objContraCheque.TipoFolha = TipoFolha;
                        if (baseIRRF != 0)
                            objContraCheque.BaseIRRF = baseIRRF;
                        else
                            objContraCheque.BaseIRRF = baseFGTS;

                        if (GetIntMes(mesFolha) == Mes && anoFolha == Ano.ToString())
                        {
                            //Grava os dados desse funcionário
                            ccADO.InserirContracheque(objContraCheque);


                            //Grava itens do contra-cheque
                            for (int i = 0; i < (listaItens.Count); i++)
                            {
                                ContrachequeItens objContraChequeitens = (ContrachequeItens)listaItens[i];
                                //gravou = DALContraCheque.GravarContraChequeItens(objContraChequeitens);
                                cciADO.InserirContrachequeItens(objContraChequeitens);
                            }
                            total_cc = total_cc + 1;//conta quantos contra-cheques foram salvos
                            //}
                            //else
                            //{
                            //    //Mostra os funcionário que apresentaram erro ao gravar na tabela Contra-cheque
                            //    erro = erro + "CPF: " + CPF + " Erro: " + gravou.Substring(35, 128) + "<BR/>";
                            //}
                        }
                        else
                        {
                            erro = "Não foi processado o arquivo o mês e ano do arquivo difere do mês e ano selecionado.";
                        }
                        //Limpa ou inicializa os campos
                        total_desc = 0; total_vant = 0; val_liq = 0;
                        num_linha_fim_func = num_linha;
                        salarioBase = 0; baseFGTS = 0; baseIRRF = 0;
                        achouLinhaInic = false; listaItens.Clear();
                    }
                }
                //Informa se o arquivo foi carregado com sucesso ou lista os erros apresentados
                //if (erro == "")
                //    lblMsg.Text = "Arquivo processado com sucesso.";
                //else
                //    lblMsg.Text = erro;
                ////Mostra quantos contra-cheques foram gravados com sucessos
                //lblTotal.Visible = true;
                //lblTotal.Text = "Total de contra-cheques gerados: " + total_cc;
            }
            return erro;
        }

        private string DescricaoFolha(int TipoFolha, int Ano, string Mes)
        {
            string descFolha = "";

            switch (TipoFolha)
            {
                case 1:
                    descFolha += "Folha do Mês ";
                    break;
                case 2:
                    descFolha += "Folha de Férias ";
                    break;
                case 3:
                    descFolha += "Folha de 13º salário ";
                    break;
            }

            switch (Mes)
            {
                case "1": descFolha += "Janeiro "; break;
                case "2": descFolha += "Fevereiro "; break;
                case "3": descFolha += "Março "; break;
                case "4": descFolha += "Abril "; break;
                case "5": descFolha += "Maio "; break;
                case "6": descFolha += "Junho "; break;
                case "7": descFolha += "Julho "; break;
                case "8": descFolha += "Agosto "; break;
                case "9": descFolha += "Setembro "; break;
                case "10": descFolha += "Outubro "; break;
                case "11": descFolha += "Novembro "; break;
                case "12": descFolha += "Dezembro "; break;
            }

            descFolha += "de " + Ano;

            return descFolha;
        }

        private string GetIntMes(string Mes)
        {
            string mesInt = "0";
            switch (Mes)
            {
                case "JAN": mesInt = "1"; break;
                case "FEV": mesInt = "2"; break;
                case "MAR": mesInt = "3"; break;
                case "ABR": mesInt = "4"; break;
                case "MAI": mesInt = "5"; break;
                case "JUN": mesInt = "6"; break;
                case "JUL": mesInt = "7"; break;
                case "AGO": mesInt = "8"; break;
                case "SET": mesInt = "9"; break;
                case "OUT": mesInt = "10"; break;
                case "NOV": mesInt = "11"; break;
                case "DEZ": mesInt = "12"; break;
            }

            return mesInt;
        }


        private bool ValidarEntradaCC(int TipoFolha, int Ano, int Mes)
        {
            try
            {
                if (TipoFolha != 1 && TipoFolha != 2 && TipoFolha != 3)
                    return false;

                if (Ano != DateTime.Now.Year && Ano != DateTime.Now.Year - 1)
                    return false;

                if (Mes != 1 && Mes != 2 && Mes != 3 && Mes != 4 && Mes != 5 && Mes != 6 && Mes != 7 && Mes != 8
                    && Mes != 9 && Mes != 10 && Mes != 11 && Mes != 12)
                    return false;
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

    }
}
